package com.kun.base.redis;

import com.kun.util.StringUtil;
import org.apache.shiro.codec.Base64;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.*;
import java.util.Set;

/**
 *
 * @author likun
 * @date 2017/4/14
 */
public class RedisClient<T> {
    private static JedisPool pool;
//    private static String redisServerIp="127.0.0.1";

    /**
     * 建立连接池
     *
     */
    private static synchronized void createJedisPool() {

        // 建立连接池配置参数
        JedisPoolConfig config = new JedisPoolConfig();

        // 设置最大连接数
        config.setMaxTotal(RedisConfig.MAX_ACTIVE);

        // 设置最大阻塞时间，记住是毫秒数milliseconds
        config.setMaxWaitMillis(RedisConfig.MAX_WAIT);

        // 设置空间连接
        config.setMaxIdle(RedisConfig.MAX_IDLE);

        // 创建连接池
        pool = new JedisPool(config, RedisConfig.HOST, RedisConfig.PORT, 3000, RedisConfig.PASS);

    }

    /**
     * 在多线程环境同步初始化
     */
    private static synchronized void poolInit() {
        if (pool == null) {
            createJedisPool();
        }
    }

    /**
     * 获取一个jedis 对象
     *
     * @return
     */
    public Jedis getJedis() {

        if (pool == null) {
            poolInit();
        }
        return pool.getResource();
    }

    /**
     * 归还一个连接
     *
     * @param jedis
     */
    private static void returnRes(Jedis jedis) {
        jedis.close();
    }

    public void set(String key, T obj) {
        jedis = getJedis();
//        jedis.append(key, serialize(obj));
        jedis.set(key, serialize(obj));
        returnRes(jedis);
    }

    public void replace(String key, T obj) {
        set(key, obj);
    }

    Jedis jedis = null;

    public void delete(String key) {
        jedis = getJedis();
        jedis.del(key);
        returnRes(jedis);
    }

    public T get(String key) {
        jedis = getJedis();
        String data=jedis.get(key);
        if (StringUtil.isEmpty(data)) {
            return null;
        }
        T obj = (T) deserialize(data);
        returnRes(jedis);
        return obj;
    }

    private static Object deserialize(String str) {
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            bis = new ByteArrayInputStream(Base64.decode(str));
            ois = new ObjectInputStream(bis);
            return ois.readObject();
        } catch (Exception e) {
            throw new RuntimeException("redis读取对象反序列化异常", e);
        } finally {
            try {
                ois.close();
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    private static String serialize(Object obj) {
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        try {
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            return Base64.encodeToString(bos.toByteArray());
        } catch (Exception e) {
            throw new RuntimeException("redis存储对象序列化异常", e);
        } finally {
            try {
                oos.close();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 获取某个字符串开头的所有key
     */
    public Set<String> keysByStr(String head){
        return getJedis().keys(head+"*");
    }
}
